package com.tsd.jxc.sale.entity;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.tsd.core.constants.Constants;
import com.tsd.core.utils.DoubleUtil;
import com.tsd.core.utils.HlpUtils;
import com.tsd.core.utils.ListUtil;
import com.tsd.jxc.buy.entity.JxcBuyOrderDetailExt;
import com.tsd.jxc.goods.entity.JxcGoodsPriceExt;
import com.tsd.jxc.sale.vo.JxcSaleContractDetailVo;
import com.tsd.jxc.stock.entity.JxcStockOutbillItemExt;
import com.tsd.jxc.vo.JxcSettingVo;
import com.tsd.jxc.vo.PrintVo;
import io.swagger.annotations.ApiModel;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 销售订单-明细扩展
 *
 * @author Hillpool
 * @date 2022/07/29 15:04:27
 */
@ApiModel(description = "销售订单-明细扩展")
public class JxcSaleOrderDetailExt extends JxcSaleOrderDetail implements Serializable {

    private List<String> order_list;

    private String order_code;

    @JsonFormat(pattern = HlpUtils.Format_Yyyy_MM_dd, locale = "zh", timezone = "GMT+8")
    private Date order_date;

    private String goods_code;

    private String goods_name;

    private String buy_order_code;

    private BigDecimal stock_qty;

    private String supplier_name;

    private String supplier_code;

    private String supplier_short_name;

    private Integer gen_bill_num;

    private BigDecimal gen_buy_qty;

    private BigDecimal gen_buy_qty4base;

    private String gen_base_unit_name;

    private String client_name;

    private String client_code;

    private String client_short_name;

    private String client_display;

    private BigDecimal buy_order_detail_qty;

    private String client_code_join;

    private String sale_order_code;

    private Long jbod_id;

    private String jbod_sid;

    private String preset_size;

    private Integer unit_qty;

    private List<JxcGoodsPriceExt> price_list;

    private BigDecimal remain_qty4base;

    public List<String> getOrder_list() {
        return order_list;
    }

    public void setOrder_list(List<String> order_list) {
        this.order_list = order_list;
    }

    public String getOrder_code() {
        return order_code;
    }

    public void setOrder_code(String order_code) {
        this.order_code = order_code;
    }

    public String getGoods_code() {
        return goods_code;
    }

    public Date getOrder_date() {
        return order_date;
    }

    public void setOrder_date(Date order_date) {
        this.order_date = order_date;
    }

    public void setGoods_code(String goods_code) {
        this.goods_code = goods_code;
    }

    public String getGoods_name() {
        return goods_name;
    }

    public void setGoods_name(String goods_name) {
        this.goods_name = goods_name;
    }

    public String getBuy_order_code() {
        return buy_order_code;
    }

    public void setBuy_order_code(String buy_order_code) {
        this.buy_order_code = buy_order_code;
    }

    public BigDecimal getStock_qty() {
        return stock_qty;
    }

    public void setStock_qty(BigDecimal stock_qty) {
        this.stock_qty = stock_qty;
    }

    public String getSupplier_name() {
        return supplier_name;
    }

    public void setSupplier_name(String supplier_name) {
        this.supplier_name = supplier_name;
    }

    public String getSupplier_code() {
        return supplier_code;
    }

    public void setSupplier_code(String supplier_code) {
        this.supplier_code = supplier_code;
    }

    public String getSupplier_short_name() {
        return supplier_short_name;
    }

    public void setSupplier_short_name(String supplier_short_name) {
        this.supplier_short_name = supplier_short_name;
    }

    public Integer getGen_bill_num() {
        return gen_bill_num;
    }

    public void setGen_bill_num(Integer gen_bill_num) {
        this.gen_bill_num = gen_bill_num;
    }

    public BigDecimal getGen_buy_qty() {
        return gen_buy_qty;
    }

    public void setGen_buy_qty(BigDecimal gen_buy_qty) {
        this.gen_buy_qty = gen_buy_qty;
    }

    public BigDecimal getGen_buy_qty4base() {
        return gen_buy_qty4base;
    }

    public void setGen_buy_qty4base(BigDecimal gen_buy_qty4base) {
        this.gen_buy_qty4base = gen_buy_qty4base;
    }

    public String getGen_base_unit_name() {
        return gen_base_unit_name;
    }

    public void setGen_base_unit_name(String gen_base_unit_name) {
        this.gen_base_unit_name = gen_base_unit_name;
    }

    public String getClient_name() {
        return client_name;
    }

    public void setClient_name(String client_name) {
        this.client_name = client_name;
    }

    public String getClient_code() {
        return client_code;
    }

    public void setClient_code(String client_code) {
        this.client_code = client_code;
    }

    public String getClient_short_name() {
        return client_short_name;
    }

    public void setClient_short_name(String client_short_name) {
        this.client_short_name = client_short_name;
    }

    public String getClient_display() {
        return client_display;
    }

    public void setClient_display(String client_display) {
        this.client_display = client_display;
    }

    public BigDecimal getBuy_order_detail_qty() {
        return buy_order_detail_qty;
    }

    public void setBuy_order_detail_qty(BigDecimal buy_order_detail_qty) {
        this.buy_order_detail_qty = buy_order_detail_qty;
    }

    public String getClient_code_join() {
        return client_code_join;
    }

    public void setClient_code_join(String client_code_join) {
        this.client_code_join = client_code_join;
    }

    public String getSale_order_code() {
        return sale_order_code;
    }

    public void setSale_order_code(String sale_order_code) {
        this.sale_order_code = sale_order_code;
    }

    public Long getJbod_id() {
        return jbod_id;
    }

    public void setJbod_id(Long jbod_id) {
        this.jbod_id = jbod_id;
    }

    public String getJbod_sid() {
        return jbod_sid;
    }

    public void setJbod_sid(String jbod_sid) {
        this.jbod_sid = jbod_sid;
    }

    public String getPreset_size() {
        return preset_size;
    }

    public void setPreset_size(String preset_size) {
        this.preset_size = preset_size;
    }

    public Integer getUnit_qty() {
        return unit_qty;
    }

    public void setUnit_qty(Integer unit_qty) {
        this.unit_qty = unit_qty;
    }

    public List<JxcGoodsPriceExt> getPrice_list() {
        return price_list;
    }

    public void setPrice_list(List<JxcGoodsPriceExt> price_list) {
        this.price_list = price_list;
    }

    public BigDecimal getRemain_qty4base() {
        return remain_qty4base;
    }

    public void setRemain_qty4base(BigDecimal remain_qty4base) {
        this.remain_qty4base = remain_qty4base;
    }

    public BigDecimal getTotal_price() {
        double price = DoubleUtil.div(this.getTotal_amount().doubleValue(), this.getQty().doubleValue(), 4);
        return BigDecimal.valueOf(price);
    }

    public void calcGoodsPrice() {
        List<JxcGoodsPriceExt> priceExtList = this.getPrice_list();
        if (!HlpUtils.isEmptyList(priceExtList)) {
            if (HlpUtils.isEmpty(this.getQty4base())) {
                JxcGoodsPriceExt priceExt = ListUtil.get(priceExtList, t -> t.getUnit_name().equals(this.getUnit_name()));
                if (priceExt != null) {
                    this.setQty4base(BigDecimal.valueOf(DoubleUtil.mul(this.getQty(), priceExt.getQty())));
                }
            }
            double baseUnitPrice = DoubleUtil.div(this.getAmount(), this.getQty4base(), 4);
            for (JxcGoodsPriceExt priceExt : priceExtList) {
                priceExt.setSale_price(BigDecimal.valueOf(DoubleUtil.mul(baseUnitPrice, priceExt.getQty())));
            }
            this.setPrice_list(priceExtList);
        }
    }

    public JxcStockOutbillItemExt genOutBillItem() {
        JxcStockOutbillItemExt itemExt = new JxcStockOutbillItemExt();
        itemExt.setGoods_sid(this.getGoods_sid());
        itemExt.setSrc_sid(this.getSid());
        itemExt.setPrice(this.getTotal_price());
        itemExt.setOut_qty(this.getQty());
        itemExt.setAmount(this.getTotal_amount());
        itemExt.setUnit_name(this.getUnit_name());
        itemExt.setGoods_name(this.getGoods_name());
        itemExt.setSn(this.getSn());
        return itemExt;
    }

    public JxcSaleReturnBillDetailExt genReturnBillDetail() {
        JxcSaleReturnBillDetailExt detailExt = new JxcSaleReturnBillDetailExt();
        detailExt.setSale_order_sid(this.getOrder_sid());
        detailExt.setSale_order_detail_sid(this.getSid());
        detailExt.setGoods_sid(this.getGoods_sid());
        detailExt.calcUnitQty(this.getQty4base(), this.getQty());
        // 剩余基本数量换算单位数量
        double qty = DoubleUtil.div(this.getRemain_qty4base(), detailExt.getUnit_qty(), 3);
        detailExt.setQty(BigDecimal.valueOf(qty));
        detailExt.setQty4base(this.getRemain_qty4base());
        // 计算未退货金额
        double amount = this.getTotal_amount().doubleValue();
        if (!HlpUtils.isEmpty(this.getReturn_amount())) {
            amount = DoubleUtil.sub(amount, this.getReturn_amount());
        }
        detailExt.setAmount(BigDecimal.valueOf(amount));
        // 计算单位单价
        detailExt.setPrice(BigDecimal.valueOf(DoubleUtil.div(amount, qty, 4)));
        detailExt.setIn_bill(Constants.DR_VALID);
        detailExt.setUnit_name(this.getUnit_name());
        detailExt.setGoods_name(this.getGoods_name());
        detailExt.setSale_order_code(this.getOrder_code());
        detailExt.setSn(this.getSn());
        detailExt.setSpec_info(this.getSpec_info());
        // 根据未退货金额及剩余基本数量计算价格
        double baseUnitPrice = DoubleUtil.div(amount, this.getRemain_qty4base(), 3);
        List<JxcGoodsPriceExt> priceExtList = ListUtil.copyList(this.getPrice_list(), JxcGoodsPriceExt.class);
        if (!HlpUtils.isEmptyList(priceExtList)) {
            for (JxcGoodsPriceExt priceExt : priceExtList) {
                double price = DoubleUtil.mul(baseUnitPrice, priceExt.getQty());
                priceExt.setSale_price(BigDecimal.valueOf(price));
            }
        }
        detailExt.setPrice_list(priceExtList);
        return detailExt;
    }

    public PrintVo convert2Print() {
        PrintVo vo = new PrintVo();
        vo.setSn(this.getSn());
        vo.setGoods_name(this.getGoods_name());
        vo.setSpec_name(this.getSpec_info());
        vo.setQty(this.getQty());
        vo.setPrice(this.getPrice());
        vo.setAmount(this.getAmount());
        vo.setNote_info(this.getNote_info());
        vo.setReturn_qty(this.getReturn_qty());
        vo.setReturn_amount(this.getReturn_amount());
        vo.setSpec_info(this.getSpec_info());
        vo.setUnit_name(this.getUnit_name());
        return vo;
    }

    public JxcBuyOrderDetailExt genBuyOrderDetail() {
        JxcBuyOrderDetailExt detailExt = new JxcBuyOrderDetailExt();
        detailExt.setGoods_sid(this.getGoods_sid());
        detailExt.setGoods_name(this.getGoods_name());
        detailExt.setGoods_code(this.getGoods_code());
        detailExt.setUnit_name(this.getUnit_name());
        detailExt.setPrice_rate(BigDecimal.ONE);
        detailExt.setTax_rate(BigDecimal.ZERO);
        detailExt.setSpec_info(this.getSpec_info());
        detailExt.setQty(this.getQty());
        detailExt.setQty4base(this.getQty4base());
        detailExt.setSale_order_detail_list(Arrays.asList(this.getSid().split(",")));
        return detailExt;
    }

    public void calc(JxcSaleOrderExt orderExt, JxcSettingVo settingVo) {
        if (HlpUtils.isEmpty(this.getTax_rate()) && !HlpUtils.isEmpty(orderExt.getTax_rate())) {
            this.setTax_rate(orderExt.getTax_rate());
        }
        if (HlpUtils.isEmpty(this.getTax_rate())) {
            this.setTax_rate(settingVo.getDefault_tax_ratio());
        }
        if (!HlpUtils.isEmpty(orderExt.getInvoice_type())) {
            this.setTax_rate(orderExt.getInvoice_type() > 0 ? this.getTax_rate() : BigDecimal.ZERO);
        }
        if (HlpUtils.isAllNotEmpty(this.getQty(), this.getPrice())) {
            double amount = DoubleUtil.mul(this.getQty(), this.getPrice());
            this.setAmount(BigDecimal.valueOf(amount));
        }
        double calcTaxAmount = 0D;
        if (!HlpUtils.isEmpty(this.getAmount())) {
            calcTaxAmount = DoubleUtil.add(calcTaxAmount, this.getAmount());
        }
        this.setTax_amount(BigDecimal.ZERO);
        if (!HlpUtils.isEmpty(this.getTax_rate())) {
            this.setTax_amount(settingVo.getTaxAmount(BigDecimal.valueOf(calcTaxAmount), this.getTax_rate(), false));
        }
        double totalAmount = DoubleUtil.add(calcTaxAmount, this.getTax_amount());
        this.setTotal_amount(BigDecimal.valueOf(totalAmount));
    }

    public JxcSaleContractDetailVo convert2ContractDetailVo() {
        JxcSaleContractDetailVo vo = new JxcSaleContractDetailVo();
        vo.setClient_code(this.getClient_code());
        vo.setQty(this.getQty());
        vo.setPrice(this.getPrice());
        vo.setAmount(this.getAmount());
        vo.setUnit(this.getUnit_name());
        vo.setNote_info(this.getNote_info());
        return vo;
    }
}
